package com.xishu.service;

import com.xishu.config.Constant;
import com.xishu.entity.AbstractEntity;
import com.xishu.entity.Company;
import com.xishu.entity.User;
import com.xishu.entity.order.OrderDiscountTicketMapping;
import com.xishu.entity.order.OrderItemMapping;
import com.xishu.entity.order.OrderTypeMapping;
import com.xishu.entity.order.OrderWaiterMapping;
import com.xishu.entity.plat.UserCompanyMapping;
import com.xishu.entity.plat.UserShopMapping;
import com.xishu.entity.shop.Catalog;
import com.xishu.entity.shop.CatalogItemMapping;
import com.xishu.entity.shop.Item;
import com.xishu.entity.shop.Shop;
import com.xishu.util.Sha256Util;
import com.xishu.util.Tools;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;

public class MappingService implements Tools {
    private static Logger logger = LoggerFactory.getLogger(MappingService.class);
    private static MappingService instance = new MappingService();

    private MappingService() {
    }

    public static MappingService getInstance() {
        return instance;
    }

    /**
     * 查询用户与企业的映射关系
     *
     * @param userId
     * @param companyId
     * @param <T>
     * @return
     * @throws Exception
     */
    public <T extends AbstractEntity> UserCompanyMapping findUserCompanyMapping(Long userId, Long companyId) throws Exception {
        String cacheKey = addTwoKey(userId, companyId);
        UserCompanyMapping userCompanyMapping = new UserCompanyMapping();
        userCompanyMapping.setUserId(userId);
        userCompanyMapping.setCompanyId(companyId);
        userCompanyMapping.setEntity(true);
        return findMapping(userCompanyMapping, cacheKey);
    }

    /**
     * 跟这个餐厅公司关联的所有公司集合
     *
     * @param companyId
     * @return
     */
    public List<UserCompanyMapping> findUserCompanyMapping(Long companyId) {
        UserCompanyMapping userCompanyMapping = new UserCompanyMapping();
        userCompanyMapping.setCompanyId(companyId);
        userCompanyMapping.setEntity(true);
        return CommonService.getInstance().searchAll(userCompanyMapping);
    }

    /**
     * 通过账号ID去查询映射
     *
     * @param userId
     * @return
     */
    public List<UserCompanyMapping> findUserCompanyMappingByUserId(Long userId) {
        UserCompanyMapping userCompanyMapping = new UserCompanyMapping();
        userCompanyMapping.setUserId(userId);
        userCompanyMapping.setEntity(true);
        return CommonService.getInstance().searchAll(userCompanyMapping);
    }

    /**
     * 查询映射关系
     *
     * @param catalogId
     * @param itemId
     */
    public CatalogItemMapping findCatalogItemMapping(Long catalogId, Long itemId) throws Exception {
        CatalogItemMapping catalogItemMapping = new CatalogItemMapping();
        catalogItemMapping.setCatalogId(catalogId);
        catalogItemMapping.setItemId(itemId);
        catalogItemMapping.setEntity(true);
        return findMapping(catalogItemMapping, addTwoKey(catalogId, itemId));
    }

    /**
     * 查询映射关系
     *
     * @param catalogId
     * @param catalogId
     */
    public List<CatalogItemMapping> findCatalogItemMappingByCatalog(Long catalogId) throws Exception {
        CatalogItemMapping catalogItemMapping = new CatalogItemMapping();
        catalogItemMapping.setCatalogId(catalogId);
        catalogItemMapping.setEntity(true);
        return CommonService.getInstance().searchAll(catalogItemMapping);
    }

    /**
     * 通过商品查询映射
     *
     * @param itemId
     * @return
     */
    public List<CatalogItemMapping> findCatalogItemMappingByItem(Long itemId) {
        CatalogItemMapping catalogItemMapping = new CatalogItemMapping();
        catalogItemMapping.setEntity(true);
        catalogItemMapping.setItemId(itemId);
        return CommonService.getInstance().searchAll(catalogItemMapping);
    }

    /**
     * 查询品类的关系
     *
     * @param itemId
     * @return
     */
    public CatalogItemMapping findCatalogItemMapping(Long itemId) throws Exception {
        CatalogItemMapping catalogItemMapping = new CatalogItemMapping();
        catalogItemMapping.setItemId(itemId);
        catalogItemMapping.setEntity(true);
        return findMapping(catalogItemMapping, addTwoKey("catalogItemMappingByItemId", itemId));
    }


    /**
     * 查询订单与商品之间的映射关系
     *
     * @param itemId
     * @param orderId
     * @param shopId
     * @return
     */
    public OrderItemMapping findOrderItemMapping(Long itemId, Long orderId, Long shopId) throws Exception {
        OrderItemMapping orderItemMapping = new OrderItemMapping();
        orderItemMapping.setOrderId(orderId);
        orderItemMapping.setItemId(itemId);
        orderItemMapping.setShopId(shopId);
        orderItemMapping.setEntity(true);
        StringBuilder stringBuilder = new StringBuilder();
        String lockKey = stringBuilder.append(shopId).append(Constant.SEPERATOR_KEY).append(orderId).append(Constant.SEPERATOR_KEY).append(itemId).toString();
        return findMapping(orderItemMapping, lockKey);
    }

    /**
     * 优惠卷与订单之间的映射
     *
     * @param orderId
     * @param ticketName
     * @param shopId
     * @return
     */
    public OrderDiscountTicketMapping findOrderDiscountMapping(Long orderId, String ticketName, Long shopId) throws Exception {
        OrderDiscountTicketMapping orderDiscountTicketMapping = new OrderDiscountTicketMapping();
        orderDiscountTicketMapping.setOrderId(orderId);
        orderDiscountTicketMapping.setName(ticketName);
        orderDiscountTicketMapping.setShopId(shopId);
        orderDiscountTicketMapping.setEntity(true);
        StringBuilder stringBuilder = new StringBuilder();
        String lockKey = stringBuilder.append(shopId).append(Constant.SEPERATOR_KEY).append(orderId).append(Constant.SEPERATOR_KEY).append(Sha256Util.sha256(ticketName)).toString();
        return findMapping(orderDiscountTicketMapping, lockKey);
    }

    /**
     * 订单与服务员之间的关系
     *
     * @param orderId
     * @param waiterName
     * @param shopId
     * @return
     */
    public OrderWaiterMapping findOrderWaiterMapping(Long orderId, String waiterName, Long shopId) throws Exception {
        OrderWaiterMapping orderWaiterMapping = new OrderWaiterMapping();
        orderWaiterMapping.setOrderId(orderId);
        orderWaiterMapping.setWaiterName(waiterName);
        orderWaiterMapping.setShopId(shopId);
        orderWaiterMapping.setEntity(true);
        StringBuilder stringBuilder = new StringBuilder();
        String lockKey = stringBuilder.append(shopId).append(Constant.SEPERATOR_KEY).append(orderId).append(Constant.SEPERATOR_KEY).append(Sha256Util.sha256(waiterName)).toString();
        return findMapping(orderWaiterMapping, lockKey);
    }

    /**
     * 查询订单类型
     *
     * @param orderId
     * @param orderType
     * @param shopId
     * @return
     */
    public OrderTypeMapping findOrderTypeMapping(Long orderId, Long orderType, Long shopId) throws Exception {
        OrderTypeMapping orderTypeMapping = new OrderTypeMapping();
        orderTypeMapping.setOrderType(orderType);
        orderTypeMapping.setOrderId(orderId);
        orderTypeMapping.setShopId(shopId);
        StringBuilder stringBuilder = new StringBuilder();
        String lockKey = stringBuilder.append(shopId).append(Constant.SEPERATOR_KEY).append(orderId).append(Constant.SEPERATOR_KEY).append(orderType).toString();
        return findMapping(orderTypeMapping, lockKey);
    }

    /**
     * 创建
     */
    public void createCatalogItemMapping(CatalogItemMapping reqCatalogItemMapping) throws Exception {
        Long itemId = reqCatalogItemMapping.getItemId();
        Long catalogId = reqCatalogItemMapping.getCatalogId();
        CatalogItemMapping catalogItemMapping = new CatalogItemMapping();
        CommonService commonService = CommonService.getInstance();
        catalogItemMapping.setCatalogId(catalogId);
        catalogItemMapping.setItemId(itemId);
        CatalogItemMapping mapping = findCatalogItemMapping(catalogId, itemId);

        if (mapping == null) {
            logger.info("will create new mapping");
            commonService.createObject(reqCatalogItemMapping);
            MappingService.getInstance().syncItemCatalogName(catalogItemMapping);
        }
    }


    /**
     * 创建账号与企业的映射
     *
     * @param userId
     * @param companyId
     * @throws Exception
     */
    public void createUserCompanyMapping(Long userId, Long companyId) throws Exception {
        UserCompanyMapping userCompanyMapping = new UserCompanyMapping();
        CommonService commonService = CommonService.getInstance();
        userCompanyMapping.setUserId(userId);
        userCompanyMapping.setCompanyId(companyId);
        UserCompanyMapping mapping = findUserCompanyMapping(userId, companyId);

        //不存在的时候创建
        if (mapping == null) {
            User user = commonService.findEntity(userId, User.class);
            userCompanyMapping.setUserName(user.getName());
            Company company = commonService.findEntity(companyId, Company.class);
            userCompanyMapping.setCompanyName(company.getName());
            CommonService.getInstance().createObject(userCompanyMapping);
        }
    }

    /**
     * 查询用户与分店的映射关系
     *
     * @param userId
     * @param shopId
     * @param <T>
     * @return
     * @throws Exception
     */
    public <T extends AbstractEntity> UserShopMapping findUserShopMapping(Long userId, Long shopId) throws Exception {
        String cacheKey = addTwoKey(userId, shopId);
        UserShopMapping userShopMapping = new UserShopMapping();
        userShopMapping.setUserId(userId);
        userShopMapping.setShopId(shopId);
        userShopMapping.setEntity(true);
        return findMapping(userShopMapping, cacheKey);
    }

    /**
     * 查询用户与分店的映射关系
     *
     * @param shopId
     * @param <T>
     * @return
     * @throws Exception
     */
    public <T extends AbstractEntity> List<UserShopMapping> findUserShopMapping(Long shopId) throws Exception {
        UserShopMapping userShopMapping = new UserShopMapping();
        userShopMapping.setShopId(shopId);
        userShopMapping.setEntity(true);
        return CommonService.getInstance().searchAll(userShopMapping);
    }

    /**
     * 通过账号ID查询分店列表
     *
     * @param userId
     * @param <T>
     * @return
     */
    public <T extends AbstractEntity> List<UserShopMapping> findUserShopMappingByUserId(Long userId) {
        UserShopMapping userShopMapping = new UserShopMapping();
        userShopMapping.setUserId(userId);
        userShopMapping.setEntity(true);
        return CommonService.getInstance().searchAll(userShopMapping);
    }

    /**
     * 创建账号与企业的映射
     *
     * @param userId
     * @param shopId
     * @throws Exception
     */
    public void createUserShopMapping(Long userId, Long shopId) throws Exception {
        logger.info("userId is {}, shopId is {}", userId, shopId);
        if (getLong(shopId) == 0) {
            return;
        }

        if (getLong(userId) == 0) {
            return;
        }

        UserShopMapping userShopMapping = new UserShopMapping();
        userShopMapping.setUserId(userId);
        userShopMapping.setShopId(shopId);

        CommonService commonService = CommonService.getInstance();
        UserShopMapping mapping = findUserShopMapping(userId, shopId);

        //不存在的时候创建
        if (mapping == null) {
            logger.info("will create new mapping");
            User user = commonService.findEntity(userId, User.class);
            userShopMapping.setUserName(user.getName());
            Shop shop = ShopService.getInstance().findShopById(shopId);
            userShopMapping.setShopName(shop.getName());
            userShopMapping.setUserName(user.getName());
            CommonService.getInstance().createObject(userShopMapping);
        }
    }

    /**
     * 查询映射关系
     *
     * @return
     */
    public <T extends AbstractEntity> T findMapping(T t, String cacheKey) throws Exception {
//        String uniqueKey = addTwoKey(t.getClass().getName(), cacheKey);
//        String entityValue = JRedisUtil.getKV(uniqueKey);
//
//        //找到了，反序列化
//        if (entityValue != null) {
//            byte[] objectByteArray = Base64.getDecoder().decode(entityValue);
//            return (T) ClassUtil.bytesToObject(objectByteArray);
//        }
//
//        //如果没有，则加锁后再读写，以防止数据不一致
//        //例如B先读，然后A写，A刷新缓存，B读后再缓存，缓存里面的数据还是没有变化过后的数据
//        LockService lockService = LockService.getInstance();
//        lockService.tryLock(uniqueKey);
//
//        try {
//            T entityInDb = CommonService.getInstance().searchOne(t);
//
//            if (entityInDb != null) {
//                byte[] bytes = ClassUtil.objectToBytes(entityInDb);
//                String objectByteArray = Base64.getEncoder().encodeToString(bytes);
//                JRedisUtil.setKV(getEntityKey(t), objectByteArray);
//                return entityInDb;
//            }
//
//            return null;
//        } finally {
//            lockService.releaseLock(uniqueKey);
//        }

        return CommonService.getInstance().searchOne(t);
    }

    /**
     * 查询绑定的账号
     *
     * @param companyId
     * @return
     */
    public List<UserCompanyMapping> searchMappingUser(Long companyId) {
        UserCompanyMapping userCompanyMapping = new UserCompanyMapping();
        userCompanyMapping.setCompanyId(companyId);
        userCompanyMapping.setEntity(true);

        return CommonService.getInstance().searchAll(userCompanyMapping);
    }

    /**
     * 添加品类的名称
     *
     * @param catalogItemMapping
     * @throws Exception
     */
    public void syncItemCatalogName(CatalogItemMapping catalogItemMapping) throws Exception {
        try {
            CommonService commonService = CommonService.getInstance();
            Long itemId = catalogItemMapping.getItemId();
            Item item = ItemService.getInstance().findItem(itemId);
            Long catalogId = catalogItemMapping.getCatalogId();
            Catalog catalog = commonService.findEntity(catalogId, Catalog.class);
            item.setCatalogName(catalog.getName());
            item.setCatalogName_zh(catalog.getName_zh());
            item.setCatalogName_en(catalog.getName_en());
            commonService.save(item);
        } catch (Exception e) {
            logger.error("e", e);
        }
    }

    /**
     * 修改余量显示
     *
     * @param itemId
     * @param leftCount
     */
    public void modifyLeftCount(Long itemId, Integer leftCount) throws Exception {
        CatalogItemMapping catalogItemMapping = new CatalogItemMapping();
        catalogItemMapping.setEntity(true);
        catalogItemMapping.setItemId(itemId);
        List<CatalogItemMapping> catalogItemMappingList = CommonService.getInstance().searchAll(catalogItemMapping);
        for (CatalogItemMapping itemMapping : catalogItemMappingList) {
            if (getInt(leftCount) <= 0) {
                itemMapping.setSaleOut(true);
            }

            itemMapping.setLeftCount(leftCount);
            CommonService.getInstance().save(itemMapping);
        }
    }

    /**
     * 删除用户分店映射关系
     *
     * @param userId
     */
    public void deleteUserShopMapping(Long userId) throws Exception {
        UserShopMapping userShopMapping = new UserShopMapping();
        userShopMapping.setBeRequest(true);
        userShopMapping.setUserId(userId);
        CommonService.getInstance().delete(userShopMapping, false);
    }

    /**
     * 删除用户与公司的映射关系
     *
     * @param userId
     */
    public void deleteUserCompanyMapping(Long userId) throws Exception {
        UserCompanyMapping userCompanyMapping = new UserCompanyMapping();
        userCompanyMapping.setBeRequest(true);
        userCompanyMapping.setUserId(userId);
        CommonService.getInstance().delete(userCompanyMapping, false);
    }


}
